const { Station } = require('../models');
const sequelize = require('sequelize');
const { Op, fn, col } = require('sequelize');
const dayjs = require('dayjs');

class StationService {
	static injector(ctn) {
		return [
			ctn.make('varal.app')
		]
	}
	constructor(app) {
		this.app = app;
	}

	async get(filter, page = 1, page_size = 20, sorter = []) {
		const { name, region = [], address, serie, contact, phone } = filter;

		const where = {};
		if (name) where['name'] = { [Op.like]: `%${name}%` };
		if (address) where['address'] = { [Op.like]: `%${address}%` };
		if (serie) where['serie'] = { [Op.regexp]: `(${serie.join('|')})` }
		if (contact) where['contact'] = { [Op.like]: `%${contact}%` }
		if (phone) where['phone'] = { [Op.like]: `%${phone}%` }

		if (region.length) {
			//多选
			if (region[0] instanceof Array) {
				const district = region.filter((d) => d[2]).map((d) => d[2]);
				const city = region.filter((d) => !d[2] && d[1]).map((d) => d[1]);
				const province = region.filter((d) => !d[1]).map((d) => d[0]);

				where[Op.and] = [
					{
						[Op.or]: [{ k: 0, v: province }, { k: 1, v: city }, { k: 2, v: district }].filter(({ v }) => v.length > 0).map(({ k, v }) => {
							return sequelize.where(fn('JSON_EXTRACT', col('Station.region'), sequelize.literal(`'$[${k}].value'`)), {
								[Op.regexp]: `(${v.map((d) => parseInt(d)).join('|')})`
							})
						})
					}
				];
			}
			//单选
			else {
				where[Op.and] = [];

				if (region[2]) {
					where[Op.and].push(fn('JSON_CONTAINS', col('region'), `{"value": ${region[2]}}`))
				} else if (region[1]) {
					where[Op.and].push(fn('JSON_CONTAINS', col('region'), `{"value": ${region[1]}}`))
				} else if (region[0]) {
					where[Op.and].push(fn('JSON_CONTAINS', col('region'), `{"value": ${region[0]}}`));
				}
			}
		}

		const { count: total, rows: data } = await Station.findAndCountAll({
			where,
			offset: (page - 1) * page_size,
			limit: page_size * 1,
			order: sorter.length ? sorter : [
				['sort', 'desc'],
				['id', 'asc']
			]
		});

		return {
			data,
			total
		}
	}

	async info(where) {
		const station = await Station.findOne({
			where
		});
		return station;
	}

	async delete(id) {
		return await Station.destroy({
			where: {
				id: { [Op.in]: String(id).split(',') }
			}
		});
	}

	async save(params) {
		['create_time', 'update_time', 'delete_time'].forEach((d) => {
			delete params[d];
		});

		const { id } = params;

		if (id) {
			return await Station.update(params, {
				where: {
					id
				}
			})
		} else {
			return await Station.create(params);
		}
	}
}

exports = module.exports = StationService;
